﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;

namespace QMERP.Application.Services
{
    public class StockActionStatisticsLogService : IStockActionStatisticsLogService
    {
        private readonly IMapper _mapper;
        private readonly QMERPDbContext _db;
        private IServiceProvider _serviceProvider;
        public StockActionStatisticsLogService(IMapper mapper, QMERPDbContext db ,IServiceProvider serviceProvider)
        {
            _mapper = mapper;
            _db = db;
            _serviceProvider = serviceProvider;
        }
        /// <summary>
        /// 出入库统计报表窗体
        /// </summary>
        /// <returns></returns>
        public async Task<PageResponse<StockActionStatisticsLogResponse>> Query(PageRequest<StockActionStatisticsLogRequest> request)
        {
            var response = new PageResponse<StockActionStatisticsLogResponse>();
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = list;
            return response;
        }
        /// <summary>
        /// 获取出入库统计报表列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<StockActionStatisticsLogResponse>> GetStockActionStatisticsLogs(PageRequest<StockActionStatisticsLogRequest> request)
        {
            var query = Where(request);
            var list = await query.ToListAsync();
            return _mapper.Map<List<StockActionStatisticsLogResponse>>(list);
        }
        private IQueryable<StockActionStatisticsLogResponse> Where(PageRequest<StockActionStatisticsLogRequest> request)
        {
            IQueryable<StockActionStatisticsLog> query = _db.StockActionStatisticsLog.Include(x => x.Warehouse).Include(x => x.Lens);
            //if (request.Query.WarehouseId != null)
            //{
            //    query = query.Where(x => x.WarehouseId == request.Query.WarehouseId);
            //}
            //if (request.Query.LensId != null)
            //{
            //    query = query.Where(x => x.LensId == request.Query.LensId);
            //}
            //var all = query.Where(x => x.InventoryDate >= request.Query.InventoryDateBegin.Date && x.InventoryDate <= request.Query.InventoryDateEnd.Date).GroupBy(x => new { WarehouseId = x.Warehouse!.Id, WarehouseCode = x.Warehouse.Code, WarehouseName = x.Warehouse.Name, LensId = x.Lens!.Id, LensCode = x.Lens.FactoryLensCode, LensName = x.Lens.FactoryLensName }).Select(s => new { WarehouseId = s.Key.WarehouseId, WarehouseCode = s.Key.WarehouseCode, WarehouseName = s.Key.WarehouseName, LensId = s.Key.LensId, LensCode = s.Key.LensCode, LensName = s.Key.LensName });

            //var opening = _db.StockActionStatisticsLogDetail.Include(x => x.StockActionStatisticsLog).Where(x => x.StockActionStatisticsLog!.InventoryDate == request.Query.InventoryDateBegin).GroupBy(x => new { x.StockActionStatisticsLog!.WarehouseId, x.StockActionStatisticsLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var closing = _db.StockActionStatisticsLogDetail.Include(x => x.StockActionStatisticsLog).Where(x => x.StockActionStatisticsLog!.InventoryDate == request.Query.InventoryDateEnd).GroupBy(x => new { x.StockActionStatisticsLog!.WarehouseId, x.StockActionStatisticsLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var purchaseIn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.PurchaseIn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var orderIn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.OrderIn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var goodsReturn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.GoodsReturn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var inventoryIn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.InventoryIn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var reworkIn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.ReworkIn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var transferIn = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.In && x.ActionLog.Reason == ActionLogReasonInEnum.TransferIn.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var saleOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.SaleOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var orderOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.OrderOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var badOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.BadOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var inventoryOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.InventoryOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var reworkOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.ReworkOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var transferOut = _db.ActionLogDetail.Include(x => x.ActionLog).Where(x => x.ActionLog!.Type == (int)ActionLogTypeEnum.Out && x.ActionLog.Reason == ActionLogReasonOutEnum.TransferOut.ToString() && x.ActionLog!.Status == (int)ActionLogStatusEnum.Finnish && x.ActionLog.CreatedOn >= request.Query.InventoryDateBegin && x.ActionLog.CreatedOn < request.Query.InventoryDateEnd.AddDays(1)).GroupBy(x => new { x.ActionLog!.WarehouseId, x.ActionLog!.LensId }).Select(s => new StockActionStatisticsLogDetailResponse { WarehouseId = s.Key.WarehouseId, LensId = s.Key.LensId, Qty = s.Sum(sum => sum.Qty) });

            //var q = (from a in all.AsNoTracking()
            //         from b in opening.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from c in closing.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from d in purchaseIn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from e in orderIn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from f in goodsReturn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from g in inventoryIn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from h in reworkIn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from i in transferIn.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from j in saleOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from k in orderOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from l in badOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from m in inventoryOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from n in reworkOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         from o in transferOut.Where(x => x.WarehouseId == a.WarehouseId && x.LensId == a.LensId).DefaultIfEmpty()
            //         select new StockActionStatisticsLogResponse
            //         {
            //             WarehouseId = a.WarehouseId,
            //             WarehouseCode = a.WarehouseCode,
            //             WarehouseName = a.WarehouseName,
            //             LensId = a.LensId,
            //             LensCode = a.LensCode,
            //             LensName = a.LensName,
            //             Opening = b.Qty == null ? 0 : b.Qty.Value,
            //             Closing = c.Qty == null ? 0 : c.Qty.Value,
            //             PurchaseIn = d.Qty == null ? 0 : d.Qty.Value,
            //             OrderIn = e.Qty == null ? 0 : e.Qty.Value,
            //             GoodsReturn = f.Qty == null ? 0 : f.Qty.Value,
            //             InventoryIn = g.Qty == null ? 0 : g.Qty.Value,
            //             ReworkIn = h.Qty == null ? 0 : h.Qty.Value,
            //             TransferIn = i.Qty == null ? 0 : i.Qty.Value,
            //             SaleOut = j.Qty == null ? 0 : j.Qty.Value,
            //             OrderOut = k.Qty == null ? 0 : k.Qty.Value,
            //             BadOut = l.Qty == null ? 0 : l.Qty.Value,
            //             InventoryOut = m.Qty == null ? 0 : m.Qty.Value,
            //             ReworkOut = n.Qty == null ? 0 : n.Qty.Value,
            //             TransferOut = o.Qty == null ? 0 : o.Qty.Value,
            //         }
            //   );
            //return q.OrderBy(x => x.WarehouseCode).ThenBy(x => x.LensCode);
            return null;
        }
    }
}
